 
/* 
 * Copyright (C) Ignacio Lucas
 */
 
/*
 *  job_event, hecho por Ignacio Lucas
 *
 *  Configuración de un evento sobre el cual la aplicación tiene interés en ser notificado.
 *
 *  Ignacio Lucas <ignacio.lucas@gmail.com>
 */
#if !defined(JOB_EVENT_H)
#define JOB_EVENT_H

// Estructura que representa la configuración de un evento de interés.
typedef struct s_job_event *job_event_t;

#include "socket.h"
#include "pipe.h"

// tipo de objeto asociado al evento (actualmente solo utilizamos las constantes JOB_SOURCE_SOCKET ,JOB_SOURCE_PIPE y JOB_SOURCE_JOB_COMM).
enum JOB_SOURCE
{
	JOB_SOURCE_SOCKET,
#define JOB_SOURCE_SOCKET 	JOB_SOURCE_SOCKET
	JOB_SOURCE_PIPE,
#define JOB_SOURCE_PIPE JOB_SOURCE_PIPE
	JOB_SOURCE_JOB_COMM,
#define JOB_SOURCE_JOB_COMM JOB_SOURCE_JOB_COMM
	JOB_SOURCE_DISK
#define JOB_SOURCE_DISK JOB_SOURCE_DISK
};

#include "server_worker.h"

/** datos que se guardan asociados al evento. Para el caso de eventos asociados a un socket, se guarda la referencia al objeto socket asociado. **/
typedef union job_event_data
{
	// si JOB_SOURCE == JOB_SOURCE_SOCKET, esta union se refiere a la configuracion del socket.
	socket_config sock_conf;

	// si JOB_SOURCE == JOB_SOURCE_PIPE, esta union se refiere a la configuracion del pipe.
	pipe_config pipe_conf;
	
	// si JOB_SOURCE == JOB_SOURCE_JOB_COMM, esta union se refiere a la configuracion del job.
	server_worker_job_comm_config server_worker_job_comm_conf;
	
} job_event_data_t;

// estructura de configuracion de un evento de interes. 
typedef struct s_job_event
{
	server_worker_job_t job; // Job que tiene interés en ser notificado por el evento.
	enum JOB_SOURCE source; // Ver enum JOB_SOURCE 
	job_event_data_t data;  // Datos asociados al job_event. Depende de source.
	int  operation;	// Operacion de configuracion a realizar. Ver enum JOB_EVENT_OP
	int  asked_events;	// Eventos en los que estamos interesados. Ver enum JOB_EVENT
	int fired_events;	// Eventos que se dispararon (respuesta).  Ver enum JOB_EVENT
	int persistent;		// la configuracion de eventos es persistente? Aplica para JOB_EVENT (INPUT|OUTPUT).
	int edge_or_level;		// 0=edge, 1=level triggered. Aplica para JOB_EVENT (INPUT|OUTPUT).
	timer_conf timeout_config; // Configuracion de timeout para el evento (con significado si (asked_events & JOB_EVENT_TIMEOUT)==1).
	void *timer_ref; // referencia a la configuracion de timers
	
} job_event;

// constantes con tipos de eventos (entrada, salida, error, hangup). 
enum JOB_EVENT
{
	JOB_EVENT_INPUT		=	0x001,
#define JOB_EVENT_INPUT JOB_EVENT_INPUT
	JOB_EVENT_OUTPUT	=	0x002,
#define JOB_EVENT_OUTPUT JOB_EVENT_OUTPUT
	JOB_EVENT_ERR 		=	0x004,
#define JOB_EVENT_ERR JOB_EVENT_ERR
	JOB_EVENT_HUP			=	0x008,
#define JOB_EVENT_HUP JOB_EVENT_HUP
	JOB_EVENT_TIMEOUT		=	0x010,	// timeout (por ejemplo, timeout de conexion (en un socket), read o write).
#define JOB_EVENT_TIMEOUT JOB_EVENT_TIMEOUT
	JOB_EVENT_CHILD_FINISHED	=	0x020,	// un job que fue lanzado por otro, acaba de finalizar.
#define JOB_EVENT_CHILD_FINISHED JOB_EVENT_CHILD_FINISHED	
	JOB_EVENT_PARENT_WAITING =	0x040	// un job que lanzo a otros, esta aguardando la finalizacion de alguno de ellos.
#define JOB_EVENT_PARENT_WAITING JOB_EVENT_PARENT_WAITING
};

// operacion de configuracion de eventos (agregar, modificar o borrar la configuracion del evento).
enum JOB_EVENT_OP
{
	JOB_EVENT_OP_ADD,
#define JOB_EVENT_OP_ADD JOB_EVENT_OP_ADD
	JOB_EVENT_OP_MOD,
#define JOB_EVENT_OP_MOD JOB_EVENT_OP_MOD
	JOB_EVENT_OP_DEL
#define JOB_EVENT_OP_DEL JOB_EVENT_OP_DEL	
};


/* 
funcion de Callback a invocar para que el interesado reciba y pueda procesar el evento disparado.
En el parametro event se especifica el valor del parametro 2 de la funcion "io_handler_register_event_interest" (ver io_handler.h)
es decir se devuelve la misma referencia a la configuracion inicial del evento, asignandose en el campo fired_events todos los eventos que hayan surgido (OR de flags descriptos en el enum JOB_EVENT).
En el parametro pending_events se indica cuantos eventos quedan pendientes de ser informados.
*/
typedef int (*event_fired_callback)(job_event_t event, int pending_events);

#endif
